import { cart, catalog, security, store } from "@mall/api-services"
import { Toast } from "antd-mobile"
import classNames from "classnames"
import * as _ from "lodash"
import * as React from "react"
import { useEffect, useState } from "react"
import Button from "../components/button"
import Divider from "../components/divider"
import Flex from "../components/flex"
import InputNumber from "../components/input-number"
import ProductPrice from "../components/product/product-price"
import Space from "../components/space"
import WhiteSpace from "../components/white-space"
import WingBlank from "../components/wing-blank"
import classes from "./option-selections.module.scss"


interface OptionValueProps {
  checked?: boolean
  label?: string
  onChange: (checked: boolean) => void
}

function OptionValue(props: OptionValueProps) {
  const { checked, label, onChange } = props
  return (<span className={classNames(classes.optionValue, {
    [classes.optionValueSelected]: checked,
  })}
                onClick={() => onChange(!checked)}>{label}</span>)
}

interface OptionProps {
  selection?: catalog.OptionSelection
  option: store.ProductOption
  onChange: (selection: catalog.OptionSelection) => void
}

function Option(props: OptionProps) {
  const { option, selection = new catalog.OptionSelection(), onChange } = props
  const { name, values } = option

  function handleChange(checked: boolean, value: store.ProductOptionValue) {
    if (checked) {
      onChange(_.assign(new catalog.OptionSelection(), {
        nameId: option.id,
        name: option.name,
        valueId: value.id,
        value: value.label,
      }))
    } else {
      onChange(_.assign(new catalog.OptionSelection(), {
        nameId: option.id,
        name: option.name,
      }))
    }
  }

  return (
    <>
      <WhiteSpace/>
      <div>{name}</div>
      <WhiteSpace/>
      <Space>
        {_.map(values, value => <OptionValue key={value.id}
                                             checked={value.id === selection.valueId}
                                             label={value.label}
                                             onChange={checked => handleChange(checked, value)}/>)}
      </Space>
    </>)
}

function selectVariant(variants: store.ProductVariant[], selections: catalog.OptionSelection[]) {
  const names = _.map(selections, selection => selection.nameId)
  const values = _.map(selections, selection => selection.valueId)

  return _.find(variants, variant => {
    const vNames = _.map(variant.optionSelections, selection => selection.nameId)
    const vValues = _.map(variant.optionSelections, selection => selection.valueId)
    return _.isEmpty(_.xor(names, vNames)) && _.isEmpty(_.xor(values, vValues))
  })
}


interface OptionSelectionsProps {
  product: store.Product
  variant: store.ProductVariant
  selections: catalog.OptionSelection[]
  onChangeSelections: (selections: catalog.OptionSelection[]) => void
  quantity: number
  onChangeQuantity: (quantity: number) => void
}

export default function OptionSelections(props: OptionSelectionsProps) {
  const { product, variant, selections, onChangeSelections, quantity, onChangeQuantity } = props
  const [imageUrl, setImageUrl] = useState("")
  const { options } = product

  useEffect(() => {
    if (_.isEmpty(selections) && !_.isEmpty(product.imageUrls)) {
      setImageUrl(product.imageUrls[0])
    } else {
      const selectedVariant = selectVariant(product.variants, selections)
      if (selectedVariant) {
        setImageUrl(selectedVariant.imageUrls[0])
      }
    }
  }, [selections, product])

  function getSelection(optionId: string) {
    return _.find(selections, selection => selection.nameId === optionId)
  }

  function handleChange(selection: catalog.OptionSelection) {
    const oSelections = _.filter(selections, oSelection => oSelection.nameId !== selection.nameId)
    onChangeSelections([...oSelections, selection])
  }


  function handleToCart() {

    if (_.isUndefined(variant) || _.isUndefined(variant.id)) {
      Toast.fail("请选择规格")
      return
    }

    const customerId = security.SecurityUserHolder.getUserId()
    const item = new cart.CartItem()
    item.productId = product.id
    item.variantId = variant.id
    item.quantity = quantity
    cart.CartServiceV1.addCartItem(customerId, item)
      .then(console.log)
  }

  return (
    <div className={classes.optionSelections}>
      <WingBlank>
        <WhiteSpace/>
        <Flex>
          <img src={imageUrl} alt="" className={classes.variantImage}/>
          <Flex direction="column" justifyContent="flex-end">
            <ProductPrice price={12.21} size={20}/>
            <span className={classes.variantId}>编号:{variant.id}</span>
          </Flex>
        </Flex>
        <WhiteSpace/>
        {_.map(options, option =>
          <Option key={option.id}
                  selection={getSelection(option.id)}
                  option={option}
                  onChange={handleChange}/>)}
        <WhiteSpace size="lg"/>
        <Flex justifyContent="space-between">
          选项
          <InputNumber min={1}
                       max={variant.inventoryQuantity}
                       value={quantity}
                       onChange={onChangeQuantity}/></Flex>
        <WhiteSpace/>
      </WingBlank>
      <footer className={classes.optionSelectionsFooter}>
        <Divider/>
        <WingBlank>
          <WhiteSpace size="sm"/>
          <Flex justifyContent="space-between" style={{ width: "100%" }}>
            <Button className={classes.button} shape="circle" type="primary"
                    onClick={handleToCart}>加入购物车</Button>
            <Button className={classes.button} shape="circle" type="primary">立即购买</Button>
          </Flex>
          <WhiteSpace size="sm"/>
        </WingBlank>
      </footer>
    </div>
  )
}
